# coding=utf-8
import requests
import json
from controller.controller_base import *
from controller.sub_data_set_controller import SubDataSetController
from controller.objsrv_controller import ObjSrvController
from flask import current_app


class SynchronizationController(ControllerBase):
    map_table = {
        GEO_LAYER_BRIDGE: {'gis_name': 'bridge', 'model': Bridge},
        GEO_LAYER_BUILDING: {'gis_name': 'building', 'model': Building},
        GEO_LAYER_CULVERT:  {'gis_name': 'culvert', 'model': Culvert},
        GEO_LAYER_DECELERATION: {'gis_name': 'deceleration', 'model': Deceleration},
        GEO_LAYER_DELINEATER: {'gis_name': 'delineater', 'model': Delineater},
        GEO_LAYER_GUARDBAR: {'gis_name': 'guardbar', 'model': GuardBar},
        GEO_LAYER_ILLUMINATION: {'gis_name': 'illumination', 'model': Illumination},
        GEO_LAYER_LANDUSE: {'gis_name': 'landuse', 'model': LandUse},
        GEO_LAYER_ROADLINE: {'gis_name': 'roadline', 'model': RoadLine},
        GEO_LAYER_ROADPOLYGON: {'gis_name': 'roadpolygon', 'model': RoadPolygon},
        GEO_LAYER_ROADSIGN: {'gis_name': 'roadsign', 'model': RoadSign},
        GEO_LAYER_TREELAWN: {'gis_name': 'treelawn', 'model': TreeLawn},
        GEO_LAYER_TUNNEL: {'gis_name': 'tunnel', 'model': TreeLawn},
        GEO_LAYER_WATER: {'gis_name': 'water', 'model': Water}
    }

    def __init__(self):
        super(SynchronizationController, self).__init__()
        self.OBJ_SRV_CONFIG = current_app.config['OBJ_SRV_CONFIG']

    def synchronous_data(self, task_id):

        task = self.db.session.query(Task).filter(
            Task.task_id == task_id).first()
        if not task:
            msg = '操作失败，任务不存在'
            writelog(msg)
            return False, msg

        # 如果任务状态不是同步中就更新为同步中
        if task.async_status != ASYNC_OBJ_ING:
            task.async_status = ASYNC_OBJ_ING
            self.db.session.commit()

        # 获取临时数据关联表的数据
        task_data_relation_list = self.db.session.query(TaskDataRelation).filter(
            TaskDataRelation.task_id == task_id,
            TaskDataRelation.async_status != ASYNC_OBJ_SUCCESSFUL
        ).all() or {}

        index = 0
        failed_cnt = 0
        for task_data_relation in task_data_relation_list:
            try:
                index += 1

                # 通过关联表获取临时表数据
                temporary_data = self.db.session.query(TemporaryData).filter(TemporaryData.data_id == task_data_relation.data_id).first()
                # 获取临时表中对应哪张正式表
                cls = self.map_table.get(temporary_data.geo_layer).get('model')
                # self.temporarily_converted_to_formal(obj, temporary_data)
                obj = self.db.session.query(cls).filter(cls.gis_id == temporary_data.gis_id).first()
                # 查询该临时数据是否存在正式数据
                data = {'key': self.OBJ_SRV_CONFIG['USER_PARAMS']['key']}
                is_create = False
                # 判断正式表的是否同步过 如果同步过则global_id必有
                if not obj.global_id:
                    # 如果没有这个id就是新数据，执行插入新数据操作
                    is_create = True
                    item_list = []
                    item = {'type': 6}
                    item_info = {}
                    detail_json = {}
                    if str(temporary_data.geom) != '' and str(temporary_data.geom) != 'None':
                        item_info['geom'] = str(temporary_data.geom)
                    item_info['owner_type'] = self.OBJ_SRV_CONFIG['OWNER_TYPE']
                    item_info['gis_name'] = self.map_table.get(temporary_data.geo_layer).get('gis_name')
                    detail_json['gis_id'] = temporary_data.gis_id
                    detail_json['class'] = temporary_data.gis_class
                    detail_json['height'] = temporary_data.height
                    item_info['detailjson'] = detail_json
                    item['item_req'] = item_info
                    item_list.append(item)
                    data['data'] = item_list
                    url = '%s%s' % (self.OBJ_SRV_CONFIG['GATE'], '/thinkphp/home/itemTest/s_item_create')
                else:
                    # 如果有这个id则为更新
                    item_req = []
                    item_info = {}
                    if str(temporary_data.geom) != '' and str(temporary_data.geom) != 'None':
                        item_info['geom'] = str(temporary_data.geom)
                    item_info['id'] = obj.global_id
                    item_info['detailjson'] = {
                        'gis_id': temporary_data.gis_id,
                        'class': temporary_data.gis_class,
                        'height': temporary_data.height
                    }
                    item_req.append(item_info)
                    data['item_req'] = item_req
                    url = '%s%s' % (self.OBJ_SRV_CONFIG['GATE'], '/thinkphp/home/itemTest/s_item_update')
                post_data = json.dumps(data)
                r = requests.post(url=url, data=post_data)
                content = r and json.loads(r.content)
                ret_code = content.get('retcode')

                if ret_code == 1:
                    # 如果是插入就将获取的global_id更新到正式表中
                    if is_create:
                        obj.global_id = content['retdata'][0]['id']
                    # 把当前关联表的状态改为同步完成
                    task_data_relation.async_status = ASYNC_OBJ_SUCCESSFUL
                else:
                    task_data_relation.async_status = ASYNC_OBJ_FAILED
                    failed_cnt += 1
                    writelog('sync failed, url=%s, post_data=%s, res=%s' % (url, post_data, content))

                writelog('synchronous_data: data_id = %s' % temporary_data.data_id)

                if index >= 100:
                    self.db.session.commit()
                    index = 0
            except:
                writelog(traceback.format_exc())

        # 完成循环
        if failed_cnt == 0:
            task.async_status = ASYNC_OBJ_SUCCESSFUL
        else:
            task.async_status = ASYNC_OBJ_FAILED
        self.db.session.commit()
        return True, '操作成功'

    def synchronous_private_data(self):
        sync_count = 0

        space_id_map = {}
        sub_set_controller = SubDataSetController()
        obj_controller = ObjSrvController()

        # 查出所有修改的数据(sm_data_trace有记录,条件是is_checked=false，sync_public=false)
        trace_list = self.db.session.query(DataTrace).filter(
            DataTrace.is_checked == False,DataTrace.sync_public == False,DataTrace.sync_private == False).limit(5000).all()

        # data_cnt = len(list(trace_list))
        for trace_item in trace_list:
            try:
                sync_count += 1
                # writelog('同步私有世界进度: %s/%s' % (sync_count, data_cnt))
                # 根据sm_data_trace表的gis_id到gs_temporary_data查数据
                data_item = self.db.session.query(TemporaryData).filter(TemporaryData.gis_id == trace_item.gis_id).first()
                if not data_item:
                    self.db.session.delete(trace_item)
                    continue
                post_data = dict()

                # 删除GIS
                if trace_item.delete_data:
                    # 临时数据
                    if data_item.global_id:
                        obj_controller.delete_obj([data_item.global_id])
                        trace_item.sync_private = True

                    # 正式数据也删掉(临时方案)
                    cls = self.map_table.get(data_item.geo_layer).get('model')
                    real_item = self.db.session.query(cls).filter(cls.gis_id == data_item.gis_id).first()
                    if real_item and real_item.global_id:
                        obj_controller.delete_obj([real_item.global_id])
                        real_item.is_is_deleted = True
                        trace_item.sync_public = True

                # 创建或者更新GIS
                else:
                    if data_item.sub_set_id not in space_id_map.keys():
                        space_id = sub_set_controller.get_space_id(data_item.sub_set_id)
                        space_id_map[data_item.sub_set_id] = space_id
                    else:
                        space_id = space_id_map.get(data_item.sub_set_id, '')

                    if space_id == '':
                        writelog('子集%s没有对应的世界信息，同步失败' % data_item.sub_set_id)
                        continue
                    item = dict()
                    detailjson = dict()
                    item['detailjson'] = detailjson
                    item['owner_type'] = 2
                    item['gis_name'] = self.map_table.get(data_item.geo_layer).get('gis_name')
                    item['parent'] = space_id
                    item['geom'] = str(data_item.geom)
                    detailjson['gis_id'] = data_item.gis_id
                    detailjson['class'] = data_item.gis_class
                    detailjson['height'] = data_item.height or '0'
                    # 如果gs_temporary_data没有global_id，调用创建物体接口，并把返回的global_id存起来
                    if not data_item.global_id:
                        data = []
                        item_info = {'item_req': item, 'type': 1}
                        data.append(item_info)
                        post_data['data'] = data
                        obj_id = obj_controller.create_obj(post_data)
                        if obj_id:
                            data_item.global_id = obj_id
                            trace_item.sync_private = True
                    # 如果gs_temporary_data有global_id，调用更新物体接口
                    else:
                        item_req = list()
                        item_req.append(item)
                        post_data['item_req'] = item_req
                        if obj_controller.update_obj(post_data):
                            trace_item.sync_private = True
            except:
                writelog(traceback.format_exc())
                continue

        self.db.session.commit()
        return sync_count


    def get_progress(self, task_id):
        successful_sql = '''SELECT COUNT(1) FROM sm_task_data_relation
                            WHERE task_id = %(task_id)d  AND async_status = 107030 AND audit_status = 106020''' % {'task_id': task_id}
        total_sql = 'SELECT COUNT(1)  FROM  sm_task_data_relation WHERE task_id = %(task_id)d  AND audit_status = 106020' % {'task_id': task_id}
        total = list(self.db.session.execute(total_sql))[0]
        successful = list(self.db.session.execute(successful_sql))[0]
        if total[0] == 0:
            return 100
        return round((float(successful[0]) / (total[0] + 0.0000001)) * 100, 2)

